﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 串口调试助手
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //变量声明区
        bool Status;
        int RX_TotalCount = 0;
        int TX_TotalCount = 0;

       //窗口运行时执行
        private void Form1_Load(object sender, EventArgs e)
        {
            //初始化下拉框索引
            comboBox1.SelectedIndex = 3;
            comboBox2.SelectedIndex = 3;
            comboBox3.SelectedIndex = 3;
            comboBox4.SelectedIndex = 0;
            comboBox5.SelectedIndex = 1;

            //设置串口下拉框不可编辑
            comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
            comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;

            Status = false;

            //InitializeComponent();
            SerialPort1.Encoding = Encoding.GetEncoding("GB2312");  // 设置串口的编码
            Control.CheckForIllegalCrossThreadCalls = false;  // 忽略多线程

            //string[] mPortNames = SerialPort1.GetPortNames();
            //this.txtPortName.Items.Clear();

            //foreach (var item in mPortNames)
            //{
            //    this.txtPortName.Items.Add(item);
            //}
        }

        //串口设备检测按钮
        private void button1_Click(object sender, EventArgs e)
        {

        }

        //打开串口按钮
        private void button2_Click(object sender, EventArgs e)
        {
            if (Status){
                button2.Text = "打开串口";
                Status = false;
                panel1.BackColor = Color.Red;
                textBox1.Enabled = false;
                SerialPort1.Close();
                button4.Enabled = false;

                comboBox1.Enabled = true;
                comboBox2.Enabled = true;
            }
            else{                               
                try
                {               
                    SerialPort1.PortName = comboBox1.Text;                      //端口号
                    SerialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);     //波特率
                    SerialPort1.DataBits = Convert.ToInt16(comboBox3.Text);     //数据位

                    SerialPort1.Parity = (System.IO.Ports.Parity)comboBox4.SelectedIndex;           //校验位
                    SerialPort1.StopBits = (System.IO.Ports.StopBits)comboBox5.SelectedIndex;        //停止位               
                    SerialPort1.Handshake = System.IO.Ports.Handshake.None;     //握手协议
        
                    //SerialPort1.Handshake = (Handshake)Enum.Parse(typeof(Handshake), setting.Handshake, true);


                    SerialPort1.Open();
                    button2.Text = "关闭串口";
                    Status = true;
                    panel1.BackColor = Color.SpringGreen;
                    textBox1.Enabled = true;
                    button4.Enabled = true;

                    //comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
                    //comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;

                    comboBox1.Enabled = false;
                    comboBox2.Enabled = false;
                }
                catch (Exception)
                {
                    MessageBox.Show("打开串口失败!","串调试助手");
                    //throw;
                }
                
            }
        }

        //下拉框事件
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex == 11)
            {
                comboBox1.DropDownStyle = ComboBoxStyle.DropDown;
            }
            else
            {
                comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
            }
            
        }
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox2.SelectedIndex == 8) 
            { 
                comboBox2.DropDownStyle = ComboBoxStyle.DropDown; 
            }
            else
            {
                comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
            }
        }

        //清空发送框
        private void button3_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
        }
        
        //清空接收框
        private void button6_Click(object sender, EventArgs e)
        {
            textBox2.Text = "";
        }

        //显示
        private void log_printf(string str,string Tab)
        {
            textBox2.Text = textBox2.Text + Tab + str;           
        }

        //串口接收事件
        private void SerialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (radioButton4.Checked)  // 如果接收模式为十六进制 
            {
                //接收字节序列直接处理
                byte[] bytes = new byte[SerialPort1.BytesToRead];
                SerialPort1.Read(bytes, 0, bytes.Length);

                //循环显示
                for (int i = 0; i < bytes.Length; i++)
                {
                    string str = Convert.ToString(bytes[i], 16).ToUpper();          // 转化为大写的16进制字符串
                    log_printf("0x" + (str.Length == 1 ? "0" + str : str) + " ","");// 如果为1个字节，前面补0， 每个数值后面加空格
                }
                log_printf("", "\r\n");
            }
            else  // 如果接收为字符串
            {

                string str = SerialPort1.ReadExisting(); //以字符串方式读
                log_printf(str,"\r\n"); // 往文本框中添加读出的文本数据
                // TebReceiveNum.AppendText(Convert.ToString(str.Length)); 
                /* 显示接收的数据长度 */
              
                RX_TotalCount += str.Length;// 接收数据的总长度 
                label7.Text = Convert.ToString(str.Length);    // 把接收到的数据的长度赋值给这个文本框显示
                label8.Text = Convert.ToString(RX_TotalCount); // 接收到的数据的总长度 界面显示 

            }
        }

        //发送按钮
        private void button4_Click(object sender, EventArgs e)
        {
            byte[] data = new byte[1]; // 定义1个字节

            if (textBox1.Text != "")  // 如果发送了数据
            {
               String dateString = textBox1.Text; // 获取要发送的字符串 
                    
               if (radioButton2.Checked)  // 如果发送是十六进制模式 
                {

                   /* 先对要发送的数据去除掉 空格 */
                   dateString = dateString.Replace(" ", ""); // 把空格去掉
                   /* 把换行符也去掉 */
                   //dateString = dateString.Replace("\r\n","");
                   //dateString = dateString.Replace("\r", "");
                   //dateString = dateString.Replace("\n", "");
                   // 每两位数据是1个字节  还考虑了发送奇数个字符的情况

                   for (int i = 0; i < (dateString.Length - dateString.Length % 2) / 2; i++)
                    {
                       // 把发送文本框的数值两个两个的发送，并且转化为16进制表示
                       data[0] = Convert.ToByte(dateString.Substring(i * 2, 2), 16);
                       SerialPort1.Write(data, 0, 1); // 从0开始写入1个字节
                    }
                    if (dateString.Length % 2 != 0)  // 剩下1位数据单独处理
                    {
                        data[0] = Convert.ToByte(dateString.Substring(dateString.Length - 1, 1), 16); // 单独发送1位
                        SerialPort1.Write(data, 0, 1); // 写入到串口
                    }

                    TX_TotalCount += dateString.Length / 2; // 发送数据总长度 程序全局变量  
                    label14.Text = Convert.ToString(dateString.Length / 2);  // 把发送缓冲区的数据的长度用发送长度文本框显示
                    label12.Text = Convert.ToString(TX_TotalCount); // 接收数据的总长度 界面显示  

                 }
                 else  // 字符串
                 {
                    try
                    {
                        /* 判断是否发送新行 */
                        if (checkBox1.Checked) // 发送新行 
                        {
                            dateString += "\r\n";
                        }
                       SerialPort1.WriteLine(dateString); // 以字符模式写数据,把要发送的数据写到串口

                       TX_TotalCount += dateString.Length / 2; // 发送数据总长度 程序全局变量  
                       label14.Text = Convert.ToString(dateString.Length / 2);  // 把发送缓冲区的数据的长度用发送长度文本框显示
                       label12.Text = Convert.ToString(TX_TotalCount); // 接收数据的总长度 界面显示  
                     }
                     catch
                     {
                       MessageBox.Show("串口数据写入错误");
                     }
                    }
                }
                else
                {
                    MessageBox.Show("请输入要发送的数据");
                }
        }

        //接收框内容发生变化
        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            textBox2.SelectionStart = textBox2.Text.Length; //设置游标起始位置
            textBox2.ScrollToCaret();                       //自动滑动到起始位置
        }        
    }
}
